/*
 * Barrier.h
 *
 *  Created on: Nov 23, 2012
 *      Author: dan
 */

#ifndef BARRIER_H_
#define BARRIER_H_

#include "Network.h"
#include "Print.hpp"

class Barrier{

	typedef boost::system::error_code error_code;

public:
	Barrier(Network& network, Network::Team team, std::string barrier_name);
	virtual ~Barrier();

public:

	void Event_OnConnection(std::string id, error_code error);
	void Event_OnDisconnection(std::string id, error_code error);
	void Event_OnMessage(std::string id, std::string message, error_code error);

	void waitConnection();
	void waitConnection(boost::mutex::scoped_lock& ext_l);
	bool wait();
	bool wait(boost::mutex::scoped_lock& ext_l);
	bool waitOne();
	bool waitOne(boost::mutex::scoped_lock& ext_l);
	void clear();

private:
	bool allConnected();
	bool allReady();
	void init();
	void printTeamStatus();
	bool inTeam(std::string id);

	inline std::string getBarrierMessage(){ return "@barrier:"+name; }

private:
	Network & network;
	Network::Team team;
	std::string name;
	size_t callbackId;

	typedef std::map<std::string, bool> HostList;
	typedef std::set<std::string> Team;
	HostList connected;
	HostList ready;
	Team teamSet;
	boost::mutex mtx;
	boost::condition_variable state_changed;

public:
	DebugPrint debug_print;
};



#endif /* BARRIER_H_ */
